﻿<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">


  <!--
  Templates used to browse manifest through templates and find the node which provide parent
  attribute to create the ralative value    
  -->

  <!-- Begin Apply template component relative attributes to deployment node-->
  <xsl:template match="relativeAttributes/*" mode="ApplyRelativeAttributeValue">
    <xsl:param name="server" />
    <xsl:param name="application" />
    <xsl:param name="middlewareTarget" />
    <xsl:param name="componentDefinition" />
    <xsl:param name="componentInstance" />

    <!-- Attribute name come from the node name belong relativeAttributes-->
    <xsl:variable name="attributeName">
      <xsl:value-of select="name()"/>
    </xsl:variable>

    <!-- searched Attribute -->
    <xsl:variable name="relativeAttribute" select="." />


    <!-- Concat targeted attribute value with relative value-->
    <xsl:attribute name="{$attributeName}">
      <xsl:apply-templates select="$server" mode="ApplyRelativeAttributeValue">
        <xsl:with-param name="server" select="$server" />
        <xsl:with-param name="application" select="$application" />
        <xsl:with-param name="middlewareTarget" select="$middlewareTarget" />
        <xsl:with-param name="componentDefinition" select="$componentDefinition" />
        <xsl:with-param name="componentInstance" select="$componentInstance" />
        <xsl:with-param name="relativeAttribute" select="$relativeAttribute" />
      </xsl:apply-templates>
    </xsl:attribute>

    <!--<xsl:copy-of select="$middleware"/>-->

  </xsl:template>
  <!-- End Apply template component relative attributes to deployment node-->

  <!-- Begin : Generic template to apply relative attribute value. Doesn't catch middleware element-->
  <xsl:template match="*" mode="ApplyRelativeAttributeValue">
    <xsl:param name="server" />
    <xsl:param name="application" />
    <xsl:param name="middlewareTarget" />
    <xsl:param name="componentDefinition" />
    <xsl:param name="componentInstance" />
    <xsl:param name="relativeAttribute" />

    <xsl:variable name="templateName" select="@template" />
    <xsl:variable name="elementName" select="name()" />

    <xsl:if test="$templateName != ''">
      <xsl:apply-templates select="//templates/template[@type=$elementName and @name= $templateName]/*" mode="ApplyRelativeAttributeValue">
        <xsl:with-param name="server" select="$server" />
        <xsl:with-param name="application" select="$application" />
        <xsl:with-param name="middlewareTarget" select="$middlewareTarget" />
        <xsl:with-param name="componentDefinition" select="$componentDefinition" />
        <xsl:with-param name="componentInstance" select="$componentInstance" />
        <xsl:with-param name="relativeAttribute" select="$relativeAttribute" />
      </xsl:apply-templates>
    </xsl:if>


    <xsl:choose>
      <xsl:when test="name()=$relativeAttribute/@targetedType and @name and @name=$relativeAttribute/@targetedName">
        <!-- The current element equals the targetedType and its name attribute equals to the targeted Name
             So we it is the searched element and we can apply the get Relative Attribute Value 
        -->
        <xsl:apply-templates select="." mode="GetRelativeValue">
          <xsl:with-param name="server" select="$server" />
          <xsl:with-param name="application" select="$application" />
          <xsl:with-param name="middlewareTarget" select="$middlewareTarget" />
          <xsl:with-param name="componentDefinition" select="$componentDefinition" />
          <xsl:with-param name="componentInstance" select="$componentInstance" />
          <xsl:with-param name="relativeAttribute" select="$relativeAttribute" />
        </xsl:apply-templates>
      </xsl:when>
      <xsl:when test="name()=$relativeAttribute/@parent and $relativeAttribute/@parent = $relativeAttribute/@targetedType">
        <!-- We are on the parent node it fits the searched targetType, so we can apply the relative value -->
        <xsl:apply-templates select="." mode="GetRelativeValue">
          <xsl:with-param name="server" select="$server" />
          <xsl:with-param name="application" select="$application" />
          <xsl:with-param name="middlewareTarget" select="$middlewareTarget" />
          <xsl:with-param name="componentDefinition" select="$componentDefinition" />
          <xsl:with-param name="componentInstance" select="$componentInstance" />
          <xsl:with-param name="relativeAttribute" select="$relativeAttribute" />
        </xsl:apply-templates>
      </xsl:when>
      <xsl:when test="name()=$relativeAttribute/@parent and $relativeAttribute/@parent != $relativeAttribute/@targetedType">
        <!-- We are on the parent node for the related attribute so we can search the targetType -->
        <!--<xsl:apply-templates select="./*/*[name()=$relativeValue/@targetedType]" mode="ApplyRelativeAttributeValue">-->
        <xsl:apply-templates select="./*" mode="ApplyRelativeAttributeValue">
          <xsl:with-param name="server" select="$server" />
          <xsl:with-param name="application" select="$application" />
          <xsl:with-param name="middlewareTarget" select="$middlewareTarget" />
          <xsl:with-param name="componentDefinition" select="$componentDefinition" />
          <xsl:with-param name="componentInstance" select="$componentInstance" />
          <xsl:with-param name="relativeAttribute" select="$relativeAttribute" />
        </xsl:apply-templates>
      </xsl:when>
      <xsl:when test="name()='executionContainer' and @name=$middlewareTarget">
        <!-- We are on a specific element which is selected by the middleware Target fron middleware parent -->
        <xsl:choose>
          <xsl:when test="name()=$relativeAttribute/@targetedType">
            <xsl:apply-templates select="." mode="GetRelativeValue">
              <xsl:with-param name="server" select="$server" />
              <xsl:with-param name="application" select="$application" />
              <xsl:with-param name="middlewareTarget" select="$middlewareTarget" />
              <xsl:with-param name="componentDefinition" select="$componentDefinition" />
              <xsl:with-param name="componentInstance" select="$componentInstance" />
              <xsl:with-param name="relativeAttribute" select="$relativeAttribute" />
            </xsl:apply-templates>
          </xsl:when>
          <xsl:otherwise>
            <!-- We are on the parent node for the related attribute so we can search the targetType -->
            <!--<xsl:apply-templates select="./*/*[name()=$relativeValue/@targetedType]" mode="ApplyRelativeAttributeValue">-->
            <xsl:apply-templates select="./*" mode="ApplyRelativeAttributeValue">
              <xsl:with-param name="server" select="$server" />
              <xsl:with-param name="application" select="$application" />
              <xsl:with-param name="middlewareTarget" select="$middlewareTarget" />
              <xsl:with-param name="componentDefinition" select="$componentDefinition" />
              <xsl:with-param name="componentInstance" select="$componentInstance" />
              <xsl:with-param name="relativeAttribute" select="$relativeAttribute" />
            </xsl:apply-templates>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:when>
      <xsl:otherwise>
        <!-- We are not on the parent type, so we have to found it -->
        <!--<xsl:apply-templates select="./*/*[name()=$relativeValue/@parent]" mode="ApplyRelativeAttributeValue">-->
        <xsl:apply-templates select="./*" mode="ApplyRelativeAttributeValue">
          <xsl:with-param name="server" select="$server" />
          <xsl:with-param name="application" select="$application" />
          <xsl:with-param name="middlewareTarget" select="$middlewareTarget" />
          <xsl:with-param name="componentDefinition" select="$componentDefinition" />
          <xsl:with-param name="componentInstance" select="$componentInstance" />
          <xsl:with-param name="relativeAttribute" select="$relativeAttribute" />
        </xsl:apply-templates>
      </xsl:otherwise>
    </xsl:choose>

  </xsl:template>
  <!-- End : Generic template to apply relative attribute value. Doesn't catch middleware element-->

  <!-- Begin : middleware template to apply relative attribute value. It must specific because we have to find sub element named
       executionContainer -->
  <xsl:template match="middleware" mode="ApplyRelativeAttributeValue">
    <xsl:param name="server" />
    <xsl:param name="application" />
    <xsl:param name="middlewareTarget" />
    <xsl:param name="componentDefinition" />
    <xsl:param name="componentInstance" />
    <xsl:param name="relativeAttribute" />

    <xsl:variable name="templateName" select="@template" />
    <xsl:variable name="elementName" select="name()" />

    <xsl:if test="$templateName != ''">
      <xsl:apply-templates select="//templates/template[@type=$elementName and @name= $templateName]/*" mode="ApplyRelativeAttributeValue">
        <xsl:with-param name="server" select="$server" />
        <xsl:with-param name="application" select="$application" />
        <xsl:with-param name="middlewareTarget" select="$middlewareTarget" />
        <xsl:with-param name="componentDefinition" select="$componentDefinition" />
        <xsl:with-param name="componentInstance" select="$componentInstance" />
        <xsl:with-param name="relativeAttribute" select="$relativeAttribute" />
      </xsl:apply-templates>
    </xsl:if>

    <xsl:apply-templates select="./executionContainer[@name=$middlewareTarget]" mode="ApplyRelativeAttributeValue">
      <xsl:with-param name="server" select="$server" />
      <xsl:with-param name="application" select="$application" />
      <xsl:with-param name="middlewareTarget" select="$middlewareTarget" />
      <xsl:with-param name="componentDefinition" select="$componentDefinition" />
      <xsl:with-param name="componentInstance" select="$componentInstance" />
      <xsl:with-param name="relativeAttribute" select="$relativeAttribute" />
    </xsl:apply-templates>

  </xsl:template>
  <!-- End : middleware template to apply relative attribute value-->

  <!-- Begin : Get Relative Value from the current node usig the relative Attribute value -->
  <xsl:template match="*" mode="GetRelativeValue">
    <xsl:param name="server" />
    <xsl:param name="application" />
    <xsl:param name="middlewareTarget" />
    <xsl:param name="componentDefinition" />
    <xsl:param name="componentInstance" />
    <xsl:param name="relativeAttribute" />

    <xsl:variable name="targetedAttributeValue" select="@*[name()=$relativeAttribute/@targetedAttribute]" />

    <!-- Concat targeted attribute value with relative value-->
    <xsl:if test="$targetedAttributeValue">
      <xsl:call-template name="EnsurePathEndTerminator">
        <xsl:with-param name="value" select="$targetedAttributeValue" />
        <xsl:with-param name="separator" select="$relativeAttribute/@separator" />
      </xsl:call-template>
      <xsl:if test="$relativeAttribute/@separator!=$relativeAttribute/@relativeValue">
        <xsl:value-of select="$relativeAttribute/@relativeValue"/>
      </xsl:if>
    </xsl:if>
  </xsl:template>
  <!-- End : Get Relative Value from the current node usig the relative Attribute value -->

  <!-- Begin : Get Relative Value from the current node usig the relative Attribute value -->
  <xsl:template match="folder[@type='application']" mode="GetRelativeValue">
    <xsl:param name="server" />
    <xsl:param name="application" />
    <xsl:param name="middlewareTarget" />
    <xsl:param name="componentDefinition" />
    <xsl:param name="componentInstance" />
    <xsl:param name="relativeAttribute" />

    <xsl:variable name="targetedAttributeValue" select="@*[name()=$relativeAttribute/@targetedAttribute]" />

    <!-- Concat targeted attribute value with relative value-->
    <xsl:if test="$targetedAttributeValue">
      <xsl:call-template name="CreateServerFolderPathForApplication">
        <xsl:with-param name="application" select="$application" />
        <xsl:with-param name="environment" select="$EnvironmentTarget" />
        <xsl:with-param name="folderPath" select="$targetedAttributeValue" />
      </xsl:call-template>
      <xsl:if test="$relativeAttribute/@separator!=$relativeAttribute/@relativeValue">
        <xsl:value-of select="$relativeAttribute/@relativeValue"/>
      </xsl:if>
    </xsl:if>
  </xsl:template>
  <!-- End : Get Relative Value from the current node usig the relative Attribute value -->


</xsl:stylesheet>
